package elmar.datastructure;

import elmar.datastructure.tree.INode;

public class TreeCoordinator {
	public static final String MARK_KEY = "coordinate";
	private static final String MARK_KEY_WIDTH = "width";
	public final LengthUnit ZERO = new LengthUnit(0, 0);
	private float m_fNodeSize;
	private float m_fCavanWidth;
	private float m_fCavanHeight;

	private INode<?> m_root;

	public TreeCoordinator(INode<?> m_root) {
		this.m_root = m_root;
	}

	public void calc() {
		_calcWidth(m_root);
		_calcPos(new NodeCoordinate(), m_root);
	}

	private void _calcWidth(INode<?> _root) {
		boolean first = true;
		LengthUnit width = ZERO;
		for (INode<?> child : _root.getChildren()) {
			_calcWidth(child);
			width = width.add((LengthUnit) child.getMark(MARK_KEY_WIDTH));
			if (!first)
				width = width.add(1, 0);
			first = false;
		}
		width = first ? new LengthUnit(0, 1) : width;
		_root.mark(MARK_KEY_WIDTH, width);
		System.out.println(_root + ":" + width);
	}

	private void _calcPos(NodeCoordinate _offset, INode<?> _node) {
		NodeCoordinate coor = new NodeCoordinate();
		LengthUnit width = (LengthUnit) _node.getMark(MARK_KEY_WIDTH);
		coor.x = new LengthUnit(width.m_fNumOfNodePad / 2,
				width.m_fNumOfNodeSize / 2 - 0.5f).add(_offset.x);
		coor.y = new LengthUnit(0, 1).add(_offset.y);
		_node.mark(MARK_KEY, coor);
		System.out.println(_node + "[" + coor.x + ',' + coor.y + ']'
				+ _node.getChildren().size());

		NodeCoordinate childOffset = new NodeCoordinate();
		childOffset.y = coor.y;
		for (INode<?> child : _node.getChildren()) {
			System.out.println("toCalc sub:" + child);
			LengthUnit childWidth = (LengthUnit) child.getMark(MARK_KEY_WIDTH);
			System.out.println(">>>>>>" + ZERO.add(ZERO));
			childOffset.x = childOffset.x.add(childWidth);
			System.out.println("toCalc-- sub:" + child);
			 childOffset.x = childOffset.x.add(new LengthUnit(0, 1));
			 _calcPos(childOffset, child);
		}
	}

	private class NodeCoordinate {
		LengthUnit x = ZERO;
		LengthUnit y = ZERO;
	}

	private static class LengthUnit {
		private final float m_fNumOfNodeSize;
		private final float m_fNumOfNodePad;

		public LengthUnit(float numOfNodePad, float numOfNodeSize) {
			m_fNumOfNodePad = numOfNodePad;
			m_fNumOfNodeSize = numOfNodeSize;
		}

		public LengthUnit add(LengthUnit _other) {
			if (_other == null)
				return this;
			return new LengthUnit(
					this.m_fNumOfNodePad + _other.m_fNumOfNodePad,
					this.m_fNumOfNodeSize + _other.m_fNumOfNodeSize);
		}

		public LengthUnit add(float _fNumOfNodePad, float _fNumOfNodeSize) {
			return new LengthUnit(this.m_fNumOfNodePad + _fNumOfNodePad,
					this.m_fNumOfNodeSize + _fNumOfNodeSize);
		}

		@Override
		public String toString() {
			return "(" + m_fNumOfNodePad + "," + m_fNumOfNodeSize + ')';
		}
	}

}
